#ifndef _HTTPSESSIONFACTORY_HPP_
#define _HTTPSESSIONFACTORY_HPP_

#include "jhdefs.hpp"
#include "types.hpp"
#include "net/URI.hpp"
#include "event/mutex.hpp"
using JHCPP::event::CMutex;
#include <map>
#include <string>

NET_NAMESPACE_BEGIN

class CHTTPSessionInstantiator;
class CHTTPClientSession;

class CHTTPSessionFactory
{
public:
	CHTTPSessionFactory();
	CHTTPSessionFactory(const std::string& proxyHost, UInt16 proxyPort);
	~CHTTPSessionFactory();

	void registerProtocol(const std::string& protocol, CHTTPSessionInstantiator* pSessionInstantiator);
	void unregisterProtocol(const std::string& protocol);
	bool supportsProtocol(const std::string& protocol);
	CHTTPClientSession* createClientSession(const CURI& uri);

	const std::string& proxyHost() const;
	UInt16 proxyPort() const;
	void setProxy(const std::string& proxyHost, UInt16 proxyPort);
	void setProxyCredentials(const std::string& username, const std::string& password);
	const std::string& proxyUsername() const;
	const std::string& proxyPassword() const;

	static CHTTPSessionFactory& defaultFactory();
private:
	struct InstantiatorInfo
	{
		CHTTPSessionInstantiator* pIn;
		int cnt;
		InstantiatorInfo(CHTTPSessionInstantiator* pInst);
		// no destructor!!! this is by purpose, don't add one!
	};


	CHTTPSessionFactory(const CHTTPSessionFactory&);
	CHTTPSessionFactory& operator = (const CHTTPSessionFactory&);

	typedef std::map<std::string, InstantiatorInfo> Instantiators;

	Instantiators	m_instantiators;
	std::string		m_proxyHost;
	UInt16			m_proxyPort;
	std::string		m_proxyUsername;
	std::string		m_proxyPassword;

	mutable CMutex	m_mutex;
};

NET_NAMESPACE_END

#endif
